/* CustomerService.java
 *
 * Copyright (C) 2013 Universidad de Sevilla
 * 
 * The use of this project is hereby constrained to the conditions of the 
 * TDG Licence, a copy of which you may download from 
 * http://www.tdg-seville.info/License.html
 * 
 */

package services;

import java.sql.Timestamp;
import java.util.Collection;
import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import repositories.CustomerRepository;
import security.LoginService;
import security.UserAccount;
import domain.Announcement;
import domain.Customer;
import domain.Registration;

@Service
@Transactional
public class CustomerService {

	// Managed repository -----------------------------------------------------
	@Autowired
	CustomerRepository customerRepository;
	// TODO: Add managed repository
	
	// Supporting services ----------------------------------------------------
	@Autowired
	AnnouncementService announcementService;
	@Autowired
	RegistrationService registrationService;
	// TODO: Add supporting services
		
	// Constructors -----------------------------------------------------------

	public CustomerService() {
		super();
	}
	
	// Simple CRUD methods ----------------------------------------------------

	public Customer create() {
		Customer result;

		// TODO: Complete this method.
		result = new Customer();

		return result;
	}

	public Collection<Customer> findAll() {
		Collection<Customer> result;

		// TODO: Complete this method.
		result = customerRepository.findAll();

		return result;
	}

	public Customer findOne(int customerId) {
		Customer result;

		// TODO: Complete this method.
		result = customerRepository.findOne(customerId);

		return result;
	}

	public void save(Customer customer) {
		// TODO: Complete this method.	
		assert customer != null;
		customerRepository.save(customer);
	}

	public void delete(Customer customer) {
		// TODO: Complete this method.
		assert customer != null;
		customerRepository.delete(customer);
	}

	// Other business methods -------------------------------------------------
	
	public Customer findByPrincipal() {
		Customer result;
		
		// TODO: Complete this method.
		UserAccount userAccount;
		
		userAccount = LoginService.getPrincipal();
		assert userAccount != null;
		result = findByUserAccount(userAccount);
		assert result != null;

		return result;
	}
	
	public Customer findByUserAccount(UserAccount userAccount) {
		Customer result;
		
		// TODO: Complete this method.
		result = customerRepository.findByUserAccountId(userAccount.getId());
		assert result != null;

		return result;
	}
	
	public void registerPrincipal(int announcementId) {
		// TODO: Complete this method.	
		Customer customer;
		Collection<Registration> registrations;
		Announcement announcement;
		Registration registration;
		Date moment;
		customer = findByPrincipal();
		registrations = customer.getRegistrations();
		announcement = announcementService.findOne(announcementId);
		registration = registrationService.createRegistration(announcement);		
		
		Assert.isTrue(!registrations.contains(registration));
		moment = new Date();
		Assert.isTrue(moment.before(announcement.getMoment()));
		
		customer.addRegistration(registration);
		registrationService.save(registration); 
		customerRepository.save(customer);
	}
	
	public void unregisterPrincipal(int announcementId) {
		// TODO: Complete this method.
		Customer customer = findByPrincipal();
		Collection<Registration> registrations = customer.getRegistrations();
		Announcement announcement = announcementService.findOne(announcementId);
		Registration registration;
		registration = registrationService.findByCustomerAndAnnouncement(customer, announcement);
		
		Assert.isTrue(registrations.contains(registration));
		Date moment = new Date();
		Assert.isTrue(moment.before(announcement.getMoment()));
		
		registration.setOwner(null);
		customer.removeRegistration(registration);
		registrationService.save(registration);
		registrationService.delete(registration); 
		customerRepository.save(customer);
	}

}